package ioc

import (
	"fmt"

	"path"
	"strings"

	"gitee.com/go-kade/librarys/http/restful/accessor/form"
	"gitee.com/go-kade/librarys/http/restful/accessor/yaml"
	"gitee.com/go-kade/librarys/http/restful/accessor/yamlk8s"
	"github.com/emicklei/go-restful/v3"
	"github.com/gin-gonic/gin"
	"google.golang.org/grpc"
)

const (
	API_NAMESPACE = "apis"
)

// 用于托管RestApi对象的Ioc空间, 最后初始化
func Api() StoreUser {
	return store.Namespace(API_NAMESPACE)
}

// ------------------------------------gin-------------------------------------------
type GinApiObject interface {
	Object
	Registry(gin.IRouter)
}

// LoadGinApi 装载所有的gin app
func LoadGinApi(pathPrefix string, root gin.IRouter) {
	objects := store.Namespace(API_NAMESPACE)
	// for v := range objects.Items {
	// 	a := objects.Items[v]
	// 	c := a.Value.(GinApiObject)
	// 	if pathPrefix != "" && !strings.HasPrefix(pathPrefix, "/") {
	// 		pathPrefix = "/" + pathPrefix
	// 	}
	// 	c.Registry(root.Group(path.Join(pathPrefix, c.Version(), c.Name())))
	// }
	objects.ForEach(func(w *ObjectWrapper) {
		api, ok := w.Value.(GinApiObject)
		if !ok {
			return
		}

		// 如果指定了 pathPrefix，并且它不以 "/" 开头，添加一个 "/"
		if pathPrefix != "" && !strings.HasPrefix(pathPrefix, "/") {
			pathPrefix = "/" + pathPrefix
		}
		//api/v1/users，这是路由组织，会是前缀
		api.Registry(root.Group(GinApiPathPrefix(pathPrefix, api)))
		// api.Registry(root.Group(path.Join(pathPrefix, api.Version(), api.Name())))
		// gin.Engine == gin.RouterGroup = gin.IRouter
	})
	//两种方案都可以
}

func GinApiPathPrefix(pathPrefix string, obj Object) string {
	// a := NewGoRestfulApiObject()
	customPrefix := obj.Meta().CustomPathPrefix
	if customPrefix != "" {
		//sssss走自定义
		// fmt.Println("-----自定义api 路径：", customPrefix)
		return customPrefix
	}

	if obj.Name() == "apidoc" {
		// cc := Api().Get(apidoc.AppName).(*restful1.SwaggerApiDoc)
		fmt.Println("-----apidoc 路径：", path.Join(pathPrefix, "gin", obj.Name()))
		pathPrefix = strings.TrimSuffix(pathPrefix, "/")
		//http://127.0.0.1:8080/default/api/cc/apidoc
		return path.Join(pathPrefix, "gin", obj.Name())
	}
	//去除字符串制定后缀
	pathPrefix = strings.TrimSuffix(pathPrefix, "/")
	//default/api/v1/hello_module 不走自定义
	fmt.Println("-----api 路径：", path.Join(pathPrefix, obj.Version(), obj.Name()))
	///default/api/v1/hello_module
	return path.Join(pathPrefix, obj.Version(), obj.Name())
}

// ----------------------------------------------------------------------------------------

// ------------------------------------go-restful-------------------------------------------
type GoRestfulApiObject interface {
	Object
	Registry(*restful.WebService)
	// 对象一些元数据, 对象的更多描述信息, 扩展使用
	// Meta() ObjectMeta
}

// LoadHttpApp 装载所有的http app
func LoadGoRestfulApi(pathPrefix string, root *restful.Container) {
	objects := store.Namespace(API_NAMESPACE)
	objects.ForEach(func(w *ObjectWrapper) {
		api, ok := w.Value.(GoRestfulApiObject)
		if !ok {
			return
		}

		ws := new(restful.WebService)
		ws.
			// Path(ApiPathPrefix(pathPrefix, api.Meta(), api))
			Path(ApiPathPrefix(pathPrefix, api)).
			Consumes(restful.MIME_JSON, form.MIME_POST_FORM, form.MIME_MULTIPART_FORM, yaml.MIME_YAML, yamlk8s.MIME_YAML).
			Produces(restful.MIME_JSON, yaml.MIME_YAML, yamlk8s.MIME_YAML)
		api.Registry(ws)
		root.Add(ws)
	})
}

// func ApiPathPrefix(pathPrefix string, obm ObjectMeta, obj Object) string {
func ApiPathPrefix(pathPrefix string, obj Object) string {
	// a := NewGoRestfulApiObject()
	customPrefix := obj.Meta().CustomPathPrefix
	if customPrefix != "" {
		//sssss走自定义
		fmt.Println("-----自定义api 路径：", customPrefix)
		return customPrefix
	}

	if obj.Name() == "apidoc" {
		// cc := Api().Get(apidoc.AppName).(*restful1.SwaggerApiDoc)
		fmt.Println("-----apidoc 路径：", path.Join(pathPrefix, "restful", obj.Name()))
		//http://127.0.0.1:8080/default/api/cc/apidoc
		return path.Join(pathPrefix, "restful", obj.Name())
	}
	//去除字符串制定后缀
	pathPrefix = strings.TrimSuffix(pathPrefix, "/")
	//default/api/v1/hello_module 不走自定义
	fmt.Println("-----api 路径：", path.Join(pathPrefix, obj.Version(), obj.Name()))
	///default/api/v1/hello_module
	return path.Join(pathPrefix, obj.Version(), obj.Name())
}

// ----------------------------------------------------------------------------------------
// type ObjectMeta struct {
// 	CustomPathPrefix string
// 	Extra            map[string]string
// }

// func (i *ObjectMeta) Meta() ObjectMeta {
// 	return NewGoRestfulApiObject()
// }

// func NewGoRestfulApiObject() ObjectMeta {
// 	return ObjectMeta{
// 		CustomPathPrefix: "",
// 		Extra:            map[string]string{},
// 	}
// }

// ---------------------------------------------
// GRPCService GRPC服务的实例
type GRPCControllerObject interface {
	Object
	Registry(*grpc.Server)
}

// LoadGrpcApp 加载所有的Grpc app
func LoadGrpcController(server *grpc.Server) {
	objects := store.Namespace(CONTROLLER_NAMESPACE)
	objects.ForEach(func(w *ObjectWrapper) {
		c, ok := w.Value.(GRPCControllerObject)
		if !ok {
			return
		}
		c.Registry(server)
	})
}

func GrpcControllerCount() int {
	count := 0
	objects := store.Namespace(CONTROLLER_NAMESPACE)
	objects.ForEach(func(w *ObjectWrapper) {
		_, ok := w.Value.(GRPCControllerObject)
		if ok {
			count++
		}
	})
	return count
}

// ---------------------------------------------
